from rest_framework.decorators import api_view
from common.response import JsonResponse
from common.constant import CODE_PARAMETER_ERROR, MSG_PARAMETER_ERROR, CODE_SUCCESS, CODE_BUSSINESS_ERROR
from .sign_models import Sign, SignCompose
from rest_framework.viewsets import ModelViewSet
from .sign_seriallzers import SignSeriallzers, SignComposeSeriallzers
from .utils import save_file, send_file, zip_dir, delele_sign
import os
import subprocess

global original_sign_apk_name
global single_sign_apk_path
global single_sign_apk_filename
global zip_sign_apk_filename
original_sign_apk_name = None
single_sign_apk_path = ''
single_sign_apk_filename = ''
zip_sign_apk_filename = ''


@api_view(['POST'])
def sign(request):
    global zip_sign_apk_filename
    try:
        sign = request.data['sign']
        signCompose = SignCompose.objects.get(id=sign)
        is_sign_success = True
        is_single = True
        id_list = signCompose.sign.split(",")
        clean_sign_result_file()
        if len(id_list) <= 1:
            is_single = True
            is_sign_success = sign_apk(id_list[0], signCompose.name)
        else:
            is_single = False
            for id in id_list:
                if not sign_apk(id, signCompose.name):
                    is_sign_success = False

        if is_sign_success:
            if is_single:
                return JsonResponse(data={"url": "resources/signResultFile/", "name": single_sign_apk_filename})
            else:
                zip_sign()
                zip_sign_apk_filename = signCompose.name+"-sign.zip"
                return JsonResponse(data={"url": "resources/signResultZip/", "name": zip_sign_apk_filename})
        else:
            return JsonResponse(data=None, code=CODE_BUSSINESS_ERROR, message="打包失败")
    except:
        return JsonResponse(data=None, code=CODE_PARAMETER_ERROR, message=MSG_PARAMETER_ERROR)


@api_view(['GET'])
def get_sign_zip_file(request):
    return send_file('static'+os.sep+'sign.zip', zip_sign_apk_filename)


@api_view(['GET'])
def get_sign_file(request):
    return send_file(single_sign_apk_path, single_sign_apk_filename)


def zip_sign():
    path = 'static' + os.sep+'sign.zip'
    target_path = get_sign_result_path()
    zip_dir(target_path, path)
    return path


def sign_apk(id, name):
    global single_sign_apk_path
    global single_sign_apk_filename

    sign = Sign.objects.get(id=id)
    sign_jar_path = 'static' + os.sep+'signapk.jar'
    apk_path = 'static' + os.sep+'sign_apk.apk'
    if original_sign_apk_name:
        apk_name = original_sign_apk_name
    else:
        apk_name = "sign.apk"
    result_file = get_sign_result_path() + os.sep+name+"-"+sign.name+'-'+apk_name
    single_sign_apk_path = result_file
    single_sign_apk_filename = name+"-"+sign.name+'-'+apk_name
    com = 'java -jar %s %s %s %s %s' % (sign_jar_path,
                                        sign.pem, sign.pk8, apk_path, result_file)
    return runcom(com)


def clean_sign_result_file():
    try:
        path = get_sign_result_path()
        for file in os.listdir(path):
            file_path = os.path.join(path, file)
            os.remove(file_path)
    except Exception as e:
        print(e)


def get_sign_result_path():
    result_path = 'static'+os.sep+'signResult'
    get_dir(result_path)
    return result_path


def runcom(command):
    result = subprocess.run(command, shell=True,
                            stderr=subprocess.PIPE, encoding='utf-8')
    if result.returncode == 0:
        return True
    else:
        return False


class SignViewSet(ModelViewSet):
    queryset = Sign.objects.all()
    serializer_class = SignSeriallzers
    pagination_class = None

    def create(self, request, *args, **kwargs):
        try:
            pem = request.FILES['pem']
            pk8 = request.FILES['pk8']
            name = request.data["name"]
            sign_path = get_sign_path(name)
            pem_path = sign_path+os.sep+'platform.x509.pem'
            pk8_path = sign_path+os.sep+'platform.pk8'
            save_file(pem, pem_path)
            save_file(pk8, pk8_path)
            Sign.objects.create(name=name, pem=pem_path, pk8=pk8_path)
            return JsonResponse(data=None, code=CODE_SUCCESS, message='签名创建成功')
        except:
            return JsonResponse(data=None, code=CODE_PARAMETER_ERROR, message=MSG_PARAMETER_ERROR)

    def destroy(self, request, *args, **kwargs):
        id = kwargs['pk']
        sign = self.queryset.get(id=id)
        if(delele_sign(sign.name)):
            sign.delete()
            return JsonResponse(data=None)
        else:
            return JsonResponse(data=None, code=CODE_BUSSINESS_ERROR, message="删除错误")


class SignComposeViewSet(ModelViewSet):
    queryset = SignCompose.objects.all()
    serializer_class = SignComposeSeriallzers
    pagination_class = None

    def create(self, request, *args, **kwargs):
        try:
            name = request.data['name']
            signs = request.data['signs']
            signChar = ""
            signsLen = len(signs)
            if signsLen > 0:
                for i in range(0, signsLen):
                    if(i + 1 >= signsLen):
                        signChar = signChar+str(signs[i])
                    else:
                        signChar = signChar+str(signs[i])+","
                SignCompose.objects.create(name=name, sign=signChar)
                return JsonResponse(data=None)
            else:
                return JsonResponse(data=None, code=CODE_PARAMETER_ERROR, message=MSG_PARAMETER_ERROR)
        except:
            return JsonResponse(data=None, code=CODE_PARAMETER_ERROR, message=MSG_PARAMETER_ERROR)


@api_view(['POST'])
def upload_sign_apk(request):
    global original_sign_apk_name
    file = request.FILES['file']
    original_sign_apk_name = file.name
    save_file(file, 'static'+os.sep+'sign_apk.apk')
    return JsonResponse(data=None)


def get_sign_path(name):
    sign_path = 'static'+os.sep+'sign'
    get_dir(sign_path)
    get_dir(sign_path+os.sep+name)
    return sign_path+os.sep+name


def get_dir(path):
    if not os.path.exists(path):
        os.mkdir(path)
